package Thread;

import java.util.Objects;
import java.util.PriorityQueue;

class MyTimeTask implements Comparable<MyTimeTask> {
    private Runnable task;
    private long time;

    public MyTimeTask(Runnable task, long time){
        this.task = task;
        this.time = time;
    }

    public long getTime(){
        return time;
    }

    public void run(){
        task.run();
    }


    @Override
    public int compareTo(MyTimeTask o) {
        return (int)(this.time - o.time);
    }
}

class MyTimer {
    private PriorityQueue<MyTimeTask> queue = new PriorityQueue<MyTimeTask>();
    private Object locker = new Object();

    public void add(Runnable task, long delay){
        synchronized (locker){
            MyTimeTask t = new MyTimeTask(task, System.currentTimeMillis() + delay);
            queue.offer(t);
            locker.notify();
        }
    }

    public MyTimer() {
        Thread thread = new Thread(() ->{
            try{
                while(true){
                    synchronized (locker){
                        while(queue.isEmpty()){
                            locker.wait();
                        }
                        MyTimeTask task = queue.peek();
                        if(System.currentTimeMillis() < task.getTime()){
                            locker.wait(task.getTime() - System.currentTimeMillis());
                        }else {
                            task.run();
                            queue.poll();
                        }
                    }
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread.start();
    }
}

public class demo2 {

    public static void main(String[] args) {
        MyTimer timer = new MyTimer();

        timer.add(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello 9000");
            }
        },9000);

        timer.add(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello 6000");
            }
        },6000);

        timer.add(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello 2000");
            }
        },2000);
    }

}
